#include <assert.h>
#include <math.h>
#include <stdint.h>
#include <stdio.h>

#include "netpbm.h"

/* Write to a PPM image
 * http://en.wikipedia.org/wiki/Portable_Gray_Map
 * http://netpbm.sourceforge.net/doc/ppm.html
 */
#define MAX_COMPONENT_VALUE 255
void writePPMbinaryImage(const char * filename, const float * data,
                         unsigned int width, unsigned int height, unsigned int stride,
                         float min, float max)
{
	FILE *f = NULL;
	uint8_t RGB[3] = {0,0,0}; /* use 3 first bytes for BGR */ 
	f = fopen(filename, "w");
	assert(f != NULL);
	fprintf(f, "P6\n"); /* Portable colormap, binary */
	fprintf(f, "%u %u\n", width, height); /* Image size */
	fprintf(f, "%u\n", MAX_COMPONENT_VALUE); /* Max component value */
	for (unsigned int i=0; i<height; i++) {
		for (unsigned int j=0; j<width; j++) {
			/* ColorMaps 
			 * http://mainline.brynmawr.edu/Courses/cs120/spring2008/Labs/ColorMaps/colorMap.py
			 */
			float weight = (data[i * stride + j] - min) / (max - min); /* [0,1] */
/*
			RGB[0] = (uint8_t) (MAX_COMPONENT_VALUE*weight+0);
			RGB[1] = (uint8_t) (0);
			RGB[2] = (uint8_t) (-MAX_COMPONENT_VALUE*weight+MAX_COMPONENT_VALUE);
*/			
			RGB[0] = 255;
			RGB[1] = 255;
			RGB[2] = 255;
			if (weight < 0.25f) {
				RGB[0] = 0;
				RGB[1] = (char) rintf(1020.0f * weight);
			} else if (weight < 0.5f) {
				RGB[0] = 0;
				RGB[2] = (char) rintf(255.0f * (1.0f + 4.0f * (0.25f - weight)));
			} else if (weight < 0.75f) {
				RGB[0] = (char) rintf(1020.0f * (weight - 0.5f));
				RGB[2] = 0;
			} else {
				RGB[1] = (char) rintf(255.0f * (1.0f + 4.0f * (0.75f - weight)));
				RGB[2] = 0;
			}
			fwrite((void *)RGB, 3, 1, f);
		}
	}
	fclose(f);
	return;
}

void writePGMASCIIImage(const char * filename, const float * data,
                        unsigned int width, unsigned int height, unsigned int stride,
                        float min, float max)
{
	FILE *f = NULL;
	f = fopen(filename, "w");
	assert(f != NULL);
	fprintf(f, "P2\n"); /* Portable colormap, binary */
	fprintf(f, "%u %u\n", width, height); /* Image size */
	fprintf(f, "%u\n", MAX_COMPONENT_VALUE); /* Max component value */
	for (unsigned int i=0; i<height; i++) {
		for (unsigned int j=0; j<width; j++) {
			float weight = (data[i * stride + j] - min) / (max - min); /* [0,1] */
			uint8_t value = MAX_COMPONENT_VALUE * weight;
			fprintf(f, "%u ", value);
		}
		fprintf(f, "\n");
	}
	fclose(f);
	return;
}
